from rest_framework.generics import ListAPIView, CreateAPIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.decorators import action
from django.db import transaction
from .serialzers import *
from .utils import get_token_user


class LabelViewSet(ModelViewSet):
    queryset = Label.objects.all()
    serializer_class = LabelSerializers

    @action(methods=['get'], detail=False)
    def users(self, request):
        """获取用户关注的标签"""
        user = get_token_user(request)
        self.queryset = self.queryset.filter(users=user)
        return self.list(request)

    @action(methods=['get'], detail=False)
    def full(self, request):
        """获取所有标签"""
        return self.list(request)

    @action(methods=['put'], detail=True)
    def focusin(self, request, pk):
        """关注标签"""
        user = get_token_user(request)
        label = self.get_object()
        label.users.add(user)
        return Response({'success':True, 'message':'ok'})

    @action(methods=['put'], detail=True)
    def focusout(self, request, pk):
        """取消关注"""
        user = get_token_user(request)
        label = self.get_object()
        label.users.remove(user)
        return Response({'success':True, 'message':'ok'})


def use_unuse(obj, user, type, unu):
    """type问题的为3，回答的为4。nun:1表示当前操作的是有用，2表示无用"""
    if unu == 1:
        # 有用
        nu = 'useful_count'
        nun = 'unuseful_count'
    else:
        nu = 'unuseful_count'
        nun = 'useful_count'
    try:
        # 查找当前用户是否对此问题已经评论过,该记录type设为3,评论过有用的userful为1
        if type == 3:
            reply = Reply.objects.get(user=user, problem=obj, type=type)
        else:
            reply = Reply.objects.get(user=user, parent=obj, type=type, problem=obj.problem)
    except Reply.DoesNotExist:
        # 没有评论过
        if type == 3:
            reply = Reply.objects.create(user=user, problem=obj, type=type)
        else:
            reply = Reply.objects.create(user=user, parent=obj, type=type, problem=obj.problem)
        setattr(reply, nu, 1)
        reply.save()
        count = getattr(obj, nu)
        setattr(obj, nu, count+1)
        obj.save()
        return Response({'success': True, 'message': 'ok'})
    if getattr(reply, nu) == 1:
        return Response({'success': False, 'message': '重复操作'})
    else:  # 改评
        setattr(reply, nu, 1)
        setattr(reply, nun, 0)
        reply.save()
        count = getattr(obj, nu)
        setattr(obj, nu, count+1)
        count_u = getattr(obj, nun)
        setattr(obj, nun, count_u-1)
        obj.save()
        return Response({'success': True, 'message': 'ok'})


class QuestionView(ModelViewSet):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializers

    # 创建问题
    def create(self, request, *args, **kwargs):
        data = request.data
        user =get_token_user(request)
        labels = data.pop('labels')
        data['user_id'] = user.id
        question = Question.objects.create(**data)
        question.labels.set(labels)
        return Response({'success':True, 'message':'ok'})

    # 问题详情
    def retrieve(self, request, *args, **kwargs):
        question = self.get_object()
        question.visits += 1
        question.save()
        data = self.get_serializer(question).data
        # 获取comment_question
        comment_objs = Reply.objects.filter(problem=question, type=0)
        comment_data = ReplySerializers(instance=comment_objs, many=True).data
        data['comment_question'] = comment_data
        # 获取answer_question
        data['answer_question'] = []
        answer_objs = Reply.objects.filter(problem=question, type=2)
        for answer_obj in answer_objs:
            comm_ans = Reply.objects.filter(parent=answer_obj, type=1)
            comm_ans_data = ReplySerializers(instance=comm_ans, many=True).data
            answer_data = ReplySerializers(instance=answer_obj).data
            answer_data['subs'] = comm_ans_data
            data['answer_question'].append(answer_data)
        return Response(data)

    @action(methods=['put'], detail=True)
    def useful(self, request, pk):
        """将问题设为有用,获取问题而且问题的有用数不能为1,否则为重复操作,修改问题中的有用数"""
        question = self.get_object()
        user = get_token_user(request)  # 当前操作用户
        # type问题的为3，回答的为4。nun:1表示当前操作的是有用，2表示无用
        return use_unuse(question, user, 3, 1)

    @action(methods=['put'], detail=True)
    def unuseful(self, request, pk):
        question = self.get_object()
        user = get_token_user(request)  # 当前操作用户
        # type问题的为3，回答的为4。nun:1表示当前操作的是有用，2表示无用
        return use_unuse(question, user, 3, 2)


class QuestionOrderView(ListAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializers

    # 根据要求排序问题
    def get_queryset(self):
        id = self.kwargs.get('id')
        if id != '-1':
            self.queryset.filter(id=int(id))
        condition = self.kwargs.get('condition')
        conditions = {'new': '-createtime', 'hot':'-reply', 'wait':'reply'}
        if condition not in conditions:
            raise serializers.ValidationError('参数错误')
        if condition != 'wait':
            return self.queryset.order_by(conditions[condition])
        else:
            return self.queryset.filter(reply=0).order_by(conditions['new'])


class ReplyViewSet(ModelViewSet):
    queryset = Reply.objects.all()
    serializer_class = ReplySerializers

    # 创建回答，需要增加问题中的回答数
    def create(self, request, *args, **kwargs):
        data = request.data
        user = get_token_user(request)
        data['user_id'] = user.id
        data['problem_id'] = data.pop('problem')
        data['parent_id'] = data.pop('parent', '')
        # with transaction.atomic:
        #     save_point = transaction.savepoint()
        reply = Reply.objects.create(**data)  # 创建回答
        question = Question.objects.get(id=data['problem_id'])
        question.reply += 1
        question.replyname = user.username
        question.replytime = reply.createtime.strftime('%Y-%m-%d')
        question.save()
        return Response({'success': True, 'message': 'ok'})

    @action(methods=['put'], detail=True)
    def useful(self, request, pk):
        """将回答设为有用,获取回答而且回答的有用数不能为1,否则为重复操作,修改问题中的有用数"""
        reply = self.get_object()
        user = get_token_user(request)  # 当前操作用户
        return use_unuse(reply, user, 4, 1)

    @action(methods=['put'], detail=True)
    def unuseful(self, request, pk):
        """将回答设为有用,获取回答而且回答的有用数不能为1,否则为重复操作,修改问题中的有用数"""
        reply = self.get_object()
        user = get_token_user(request)  # 当前操作用户
        # type问题的为3，回答的为4。nun:1表示当前操作的是有用，2表示无用
        return use_unuse(reply, user, 4, 2)







